#include "tp2.h"

static double tempototal = 0;	//external static: restringe a visibilidade dessa variável para somente as funções declaradas neste arquivo

char *elapsedtime(struct timeval *told, struct timeval *tnew) {
	char *s = (char *) calloc(12, sizeof(char));	//calloc() zera a memória alocada
	double tempo =
		(double) (((tnew->tv_sec * 1000000 + tnew->tv_usec) -
				   (told->tv_sec * 1000000 + told->tv_usec)) / 1000000.0);

	tempototal += tempo;
	snprintf(s, 12, "%.6f", tempo);
	return s;
}

int main() {
	CLIENT *cl;					// descriptor para client
	char *clnt_res = (char *) malloc(QUERY_RESULT_SIZE * sizeof(char));	// retorno da query
	float salario = 123.45;		// not null
	char *query = (char *) malloc(QUERY_SIZE * sizeof(char));;	// 'INSERT', 'SELECT' ou 'DELETE'
	enum clnt_stat ret_stat;
	int i;
	struct timeval tvold, tvnew;
	char *t_elap;

	cl = clnt_create("x-men", TP2_PROG, TP2_VERS, "tcp");
	if (cl == NULL) {
		fprintf(stderr, "criacao do cliente falhou\n");
		exit(1);
	}

	/* cria autenticacao AUTH _UNIX (Unix Authentication) */
	auth_destroy((AUTH *) cl->cl_auth);
	cl->cl_auth = (AUTH *) authunix_create_default();

	for (i = 0; i < 100; i++) {
		if (i % 5)				//inclui Ramal
			sprintf(query,
					"INSERT INTO funcionarios(Nome, Cargo, Ramal, Salario) VALUES('Fulano%d', 'Cargo%d', '%d', '%.2f');",
					i, i % 10, 1234 + i, salario + (float) i);
		else					//não inclui Ramal, ou seja, deixa NULL
			sprintf(query,
					"INSERT INTO funcionarios(Nome, Cargo, Salario) VALUES('Fulano%d', 'Cargo%d', '%.2f');",
					i, i % 10, salario + (float) i);
		gettimeofday(&tvold, NULL);
		ret_stat = query_1(&query, &clnt_res, cl);
		if (ret_stat != RPC_SUCCESS) {	//faz o tratamento do retorno da rpc, se houver erro.
			switch (ret_stat) {
			case RPC_CANTENCODEARGS:
				fprintf(stderr, "ERRO no rpc: can't encode arguments\n");
				break;
			case RPC_CANTDECODERES:
				fprintf(stderr, "ERRO no rpc: can't decode results\n");
				break;
			case RPC_CANTSEND:
				fprintf(stderr, "ERRO no rpc: failure in sending call\n");
				break;
			case RPC_CANTRECV:
				fprintf(stderr, "ERRO no rpc: failure in receiving result\n");
				break;
			default:
				fprintf(stderr, "ERRO no rpc: generic error\n");
				break;
			}
			free(clnt_res);
			free(query);
			exit(1);
		}
		gettimeofday(&tvnew, NULL);
		t_elap = elapsedtime(&tvold, &tvnew);
		printf("Query: %s\n", query);
		printf("Resultado:\n");	//não tem resultado para INSERT
		printf("Tempo de resposta: %s\n\n", t_elap);
		free(t_elap);
	}

	for (i = 0; i < 50; i++) {
		sprintf(query, "SELECT * FROM funcionarios WHERE salario<=200.00;");
		gettimeofday(&tvold, NULL);
		if (query_1(&query, &clnt_res, cl) != RPC_SUCCESS) {
			fprintf(stderr, "erro no RPC\n");
			exit(1);
		}
		gettimeofday(&tvnew, NULL);
		t_elap = elapsedtime(&tvold, &tvnew);
		printf("Query: %s\n", query);
		printf("Resultado:\n%s", clnt_res);
		printf("Tempo de resposta: %s\n\n", t_elap);
		free(t_elap);

		sprintf(query, "SELECT * FROM funcionarios WHERE salario>200.00;");
		gettimeofday(&tvold, NULL);
		if (query_1(&query, &clnt_res, cl) != RPC_SUCCESS) {
			fprintf(stderr, "erro no RPC\n");
			exit(1);
		}
		gettimeofday(&tvnew, NULL);
		t_elap = elapsedtime(&tvold, &tvnew);
		printf("Query: %s\n", query);
		printf("Resultado:\n%s", clnt_res);
		printf("Tempo de resposta: %s\n\n", t_elap);
		free(t_elap);
	}

	for (i = 0; i < 100; i++) {
		sprintf(query, "DELETE FROM funcionarios WHERE Nome='Fulano%d';", i);
		gettimeofday(&tvold, NULL);
		if (query_1(&query, &clnt_res, cl) != RPC_SUCCESS) {
			fprintf(stderr, "erro no RPC\n");
			exit(1);
		}
		gettimeofday(&tvnew, NULL);
		t_elap = elapsedtime(&tvold, &tvnew);
		printf("Query: %s\n", query);
		printf("Resultado:\n");	//não tem resultado para DELETE
		printf("Tempo de resposta: %s\n\n", t_elap);
		free(t_elap);
	}
	printf("\nSoma de todos os tempos: %.6f\n", tempototal);
	free(clnt_res);
	free(query);
	return 0;
}
